%%

%byaccj

%{
  private Parser yyparser;
  public Yylex(java.io.Reader r, Parser yyparser) {
    this(r);
    this.yyparser = yyparser;
  }
%}

%line
%column

LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace = {LineTerminator} | [ \t\f]
Comment = {TraditionalComment} | {EndOfLineComment} 
TraditionalComment = "/*" [^*] ~"*/" | "/*" "*"+ "/"
EndOfLineComment = "//" {InputCharacter}* {LineTerminator}?
ID = [:jletter:][:jletterdigit:]*
INTCONST = 0 | [1-9][0-9]*
STRINGC = [^\r\n\"\\]
CHARCONST = [^\r\n\'\\]
%state STRING, CHARLITERAL

%%

<YYINITIAL> {

  "break"                        { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.BREAK;}
  "char"                         { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.CHAR;}
  "else"                         { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.ELSE;}
  "int"                          { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.INT;}
  "if"                           { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.IF;}
  "return"                       { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.RETURN;}
  "while"                        { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.WHILE;}
  "write"                        { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.WRITE;}
  "read"                         { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.READ;}
  "writeln"                      { System.out.println("RESERVADA " + yytext() + " " + (yyline + 1)); return yyparser.WRITELN;} 
  "("                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.PTE; }
  ")"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.PTD; }
  "{"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.CHE; }
  "}"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.CHD; }
  "["                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.CCE; }
  "]"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.CCD; }
  ";"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.PTVG; }
  ","                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.VRG; }
  "."                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.DOT; }
  "="                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.ATR; }
  ">"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREP; }
  "<"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREM; }
  "!"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.EXCL; }
  "~"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.COMP; }
  "?"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.QUESTION; }
  ":"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.COLON; }
  "=="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREII; }
  "<="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREMI; }
  ">="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREPI; }
  "!="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.ORED; }
  "&&"                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREEE; }
  "||"                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREOU; }
  "++"                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPPP; }
  "--"                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPLL; }
  "+"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPP; }
  "-"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPL; }
  "*"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPM; }
  "/"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OPD; }
  "&"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.AND; }
  "|"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OR; }
  "^"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.XOR; }
  "%"                            { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.MOD; }
  "+="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.PLUSEQ; }
  "-="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.MINUSEQ; }
  "*="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.MULTEQ; }
  "/="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.DIVEQ; }
  "&="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.ANDEQ; }
  "|="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.OREQ; }
  "^="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.XOREQ; }
  "%="                           { System.out.println(yytext()+  " " + yytext() + " " + (yyline + 1)); return yyparser.MODEQ; }
  \"                             { yybegin(STRING);}
  \'                             { yybegin(CHARLITERAL); }
  {Comment}                      {/* ignore */ }
  {WhiteSpace}                   {/* ignore */ }
  {ID}                   { System.out.println("ID "+ yytext() + " " + (yyline + 1));
								  yyparser.yylval = new ParserVal(yytext());
								  return Parser.ID;}   
  {INTCONST}           		 { System.out.println("NUM " + yytext() + " " + (yyline + 1)); yyparser.yylval = new ParserVal(Integer.parseInt(yytext()));
								  return Parser.NUM; }
}

<STRING> {
  \"                             { yybegin(YYINITIAL); 
								  System.out.println("STR " + yytext() + " " + (yyline + 1)); 
                                  yyparser.yylval = new ParserVal(yytext());
								  return Parser.SRT;
								 }
  {STRINGC}+                     {}  
  /* casos de erro */
  \\.                            { System.out.println("ERRO: Illegal escape sequence \""+yytext()+"\""); }
  {LineTerminator}               { System.out.println("ERRO: CADEIA DE CARACTERES OCUPA MAIS DE UMA LINHA"); }
}

<CHARLITERAL> {
  {CHARCONST}\'            			  { yybegin(YYINITIAL); 
									System.out.println("CHAR " + yytext() + " " + (yyline + 1));
									yyparser.yylval = new ParserVal(yytext());
                                    return Parser.CCHAR; 
                                  }  
  \\.                            { System.out.println("ERRO: Illegal escape sequence \""+yytext()+"\""); }
  {LineTerminator}               { System.out.println("ERRO: Unterminated character literal at end of line"); }
}

.|\n                             { System.out.println("ERRO: Illegal character \""+yytext()+
                                                             "\" at line "+yyline+", column "+yycolumn); }

